article.guide
  carousel.deck.container-fluid
    slide.row-fluid
      .col-sm-3
        h3 Northwind Graph
        p.lead From RDBMS to Graph, using a classic dataset
      .col-sm-9
        p The
          em Northwind Graph
          |  demonstrates how to migrate from a
          | relational database to Neo4j. The transformation
          | is iterative and deliberate, emphasizing the conceptual shift from
          | relational tables to the nodes and relationships of a graph.
        p This guide will show you how to:
        ol.big
          li Load: create data from external CSV files
          li Index: index nodes based on label
          li Relate: transform foreign key references into data relationships
          li Promote: transform join records into relationships
    slide.row-fluid
      .col-sm-3
        h3 Product Catalog
        p Northwind sells food products in a few categories, provided by suppliers.
          | Let's start by loading the product catalog tables.
        p The load statements to the right require public internet access.
          code LOAD CSV
          |  will retrieve a CSV file from a valid URL, applying a Cypher statement to
          | each row using a named map (here we're using the name `row`).
        p
          img.img-responsive(src='images/northwind/product-category-supplier.png')
        hr
        p
          small :help
          | &nbsp;
          a(help-topic='cypher') cypher
          | &nbsp;
          a(help-topic='load-csv') LOAD CSV
      .col-sm-9
        h4 Load records
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/products.csv" AS row
            CREATE (n:Product)
            SET n = row,
              n.unitPrice = toFloat(row.unitPrice),
              n.unitsInStock = toInt(row.unitsInStock), n.unitsOnOrder = toInt(row.unitsOnOrder),
              n.reorderLevel = toInt(row.reorderLevel), n.discontinued = (row.discontinued &lt;&gt; "0")
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/categories.csv" AS row
            CREATE (n:Category)
            SET n = row
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/suppliers.csv" AS row
            CREATE (n:Supplier)
            SET n = row
        h4 Create indexes
        figure
          pre.pre-scrollable.code.runnable.
            CREATE INDEX ON :Product(productID)
        figure
          pre.pre-scrollable.code.runnable.
            CREATE INDEX ON :Category(categoryID)
        figure
          pre.pre-scrollable.code.runnable.
            CREATE INDEX ON :Supplier(supplierID)
    slide.row-fluid
      .col-sm-3
        h3 Product Catalog Graph
        p The products, categories and suppliers are related through foreign key references.
          | Let's promote those to data relationships to realize the graph.
        p
          img.img-responsive(src='images/northwind/product-graph.png')
        hr
        p
          small :help
          | &nbsp;
          a(help-topic='cypher') cypher
          | &nbsp;
          a(help-topic='match') MATCH
      .col-sm-9
        h4 Create data relationships
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (p:Product),(c:Category)
            WHERE p.categoryID = c.categoryID
            CREATE (p)-[:PART_OF]-&gt;(c)
          include ../../views/partials/inefficient-cypher-query
          figcaption Calculate join, materialize relationship. (See&nbsp;
            a(href="http://neo4j.com/developer/guide-importing-data-and-etl")&nbsp; importing guide
            |  for more details)
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (p:Product),(s:Supplier)
            WHERE p.supplierID = s.supplierID
            CREATE (s)-[:SUPPLIES]-&gt;(p)
          include ../../views/partials/inefficient-cypher-query
    slide.row-fluid
      .col-sm-3
        h3 Querying Product Catalog Graph
        p Lets try some queries using patterns.
        p
          img.img-responsive(src='images/northwind/product-graph.png')
        hr
        p
          small :help
          | &nbsp;
          a(help-topic='cypher') cypher
          | &nbsp;
          a(help-topic='match') MATCH
      .col-sm-9
        h4 Query using patterns
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (s:Supplier)--&gt;(:Product)--&gt;(c:Category)
            RETURN s.companyName as Company, collect(distinct c.categoryName) as Categories
          figcaption List the product categories provided by each supplier.
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (c:Category {categoryName:"Produce"})&lt;--(:Product)&lt;--(s:Supplier)
            RETURN DISTINCT s.companyName as ProduceSuppliers
          figcaption Find the produce suppliers.
    slide.row-fluid
      .col-sm-3
        h3 Customer Orders
        p Northwind customers place orders which may detail multiple
          | products.
          img.img-responsive(src='images/northwind/customer-orders.png')
        hr
        p
          small :help
          | &nbsp;
          a(help-topic='cypher') cypher
          | &nbsp;
          a(help-topic='load-csv') LOAD CSV
      .col-sm-9
        h4 Load and index records
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/customers.csv" AS row
            CREATE (n:Customer)
            SET n = row
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/orders.csv" AS row
            CREATE (n:Order)
            SET n = row
        figure
          pre.pre-scrollable.code.runnable.
            CREATE INDEX ON :Customer(customerID)
        figure
          pre.pre-scrollable.code.runnable.
            CREATE INDEX ON :Order(orderID)
        h4 Create data relationships
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (c:Customer),(o:Order)
            WHERE c.customerID = o.customerID
            CREATE (c)-[:PURCHASED]-&gt;(o)
          include ../../views/partials/inefficient-cypher-query
    slide.row-fluid
      .col-sm-3
        h3 Customer Order Graph
        p Notice that Order Details are always part of an Order and that they
          i relate
          |  the Order to a Product &mdash; they're a join table. Join tables
          | are always a sign of a data relationship, indicating shared information
          | between two other records.
        p Here, we'll directly promote each OrderDetail record into a relationship in the graph.
          img.img-responsive(src='images/northwind/order-graph.png')
        hr
        p
          small :help
          | &nbsp;
          a(help-topic='cypher') cypher
          | &nbsp;
          a(help-topic='load-csv') LOAD CSV
      .col-sm-9
        h4 Load and index records
        figure
          pre.pre-scrollable.code.runnable.
            LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/order-details.csv" AS row
            MATCH (p:Product), (o:Order)
            WHERE p.productID = row.productID AND o.orderID = row.orderID
            CREATE (o)-[details:ORDERS]-&gt;(p)
            SET details = row,
              details.quantity = toInt(row.quantity)
          include ../../views/partials/inefficient-cypher-query
        h4 Query using patterns
        figure
          pre.pre-scrollable.code.runnable.
            MATCH (cust:Customer)-[:PURCHASED]-&gt;(:Order)-[o:ORDERS]-&gt;(p:Product),
                  (p)-[:PART_OF]-&gt;(c:Category {categoryName:"Produce"})
            RETURN DISTINCT cust.contactName as CustomerName, SUM(o.quantity) AS TotalProductsPurchased

    slide.row-fluid.header
      .col-sm-4
        h4 Northwind Graph
        br
        h3 Next steps
      .col-sm-4
        h3 More code
        ul.undecorated
          li
            a(play-topic='movie-graph') Movie Graph
            |  - actors &amp; movies
          li
            a(play-topic='query-template') Query Templates
            |  - common ad-hoc queries
          li
            a(play-topic='cypher') Cypher
            |  - query language fundamentals
      .col-sm-4
        h3 Reference
        ul.undecorated
          li
            a(href='http://neo4j.com/developer/guide-importing-data-and-etl/') Full Northwind import example
          li
            a(href='http://neo4j.com/developer') Developer resources
          li
            a(href='{{ neo4j.version | neo4jDeveloperDoc }}/') Neo4j Developer Manual
